package com.zzx.resource.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 自定义资源服务器获取认证信息
 **/
@Component
public class MyUserAuthenticationConverter extends DefaultUserAuthenticationConverter {
    private static final String N_A = "N/A";
    private static final String USERID = "user_id";
    private static final String USERTYPE = "user_type";
    private static final String DEPTID = "dept_id";
    private static final String NICKNAME = "nickName";
    private static final String WECHATUSERID = "wechat_user_id";
//    @Autowired
//    private AuthoritiesService authoritiesService;

    @Autowired
    StringRedisTemplate redisTemplate;

    /**
     * 将授权信息返回到资源服务
     */
    @Override
    public Map<String, ?> convertUserAuthentication(Authentication userAuthentication) {
        Map<String, Object> authMap = new LinkedHashMap<>();
        authMap.put(USERNAME, userAuthentication.getName());
        if (userAuthentication.getAuthorities() != null && !userAuthentication.getAuthorities().isEmpty()) {
            authMap.put(AUTHORITIES, AuthorityUtils.authorityListToSet(userAuthentication.getAuthorities()));
        }
        return authMap;
    }

    /**
     * 用户认证信息
     *
     */
    @Override
    public Authentication extractAuthentication(Map<String, ?> map) {
        if (map.containsKey(USERNAME)) {
//            Collection<? extends GrantedAuthority> authorities = getAuthorities(map);
            // 自定义用户信息放到Security Context中方便业务获取
            String userId = String.valueOf(map.get(USERID));
            int userType = (Integer) map.get(USERTYPE);
            String username = (String) map.get(USERNAME);
            String deptId = String.valueOf(map.get(DEPTID));
            String nickname = (String) map.get(NICKNAME);
            String wechatUserId = (String) map.get(WECHATUSERID);
            String sysDeptJs = redisTemplate.opsForValue().get("login:self:dept:" + deptId);
            String listJs = redisTemplate.opsForValue().get("login:subofgroup:user:" + userId);
            Set<String> perms = redisTemplate.opsForSet().members("login:perms:user:" + userId);
            Collection<? extends GrantedAuthority> authorities = null;

            if (perms != null && perms.size() > 0) {
                String permStr = perms.stream().collect(Collectors.joining(","));
                authorities = AuthorityUtils.commaSeparatedStringToAuthorityList(permStr);
            }
            if (authorities == null) {
                authorities = new HashSet<>();
            }
//            Collection<? extends GrantedAuthority> authorities = authoritiesService.getAuthorities(username);
            LoginUser user = new LoginUser(userId, wechatUserId, userType, nickname, username, N_A, true, true, true, true, authorities);
            return new UsernamePasswordAuthenticationToken(user, N_A, authorities);
        }
        return null;
    }

    /**
     * 获取权限资源信息
     */
    private Collection<? extends GrantedAuthority> getAuthorities(Map<String, ?> map) {
        Object authorities = map.get(AUTHORITIES);
        if (authorities instanceof String) {
            return AuthorityUtils.commaSeparatedStringToAuthorityList((String) authorities);
        }
        if (authorities instanceof Collection) {
            return AuthorityUtils.commaSeparatedStringToAuthorityList(
                    StringUtils.collectionToCommaDelimitedString((Collection<?>) authorities));
        }
        return null;
    }
}
